package com.yida.auth.service;

import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.yida.common.core.constant.CacheConstants;
import com.yida.common.core.constant.Constants;
import com.yida.common.core.constant.SecurityConstants;
import com.yida.common.core.domain.R;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.redis.service.RedisService;
import com.yida.common.security.utils.SecurityUtils;
import com.yida.system.api.RemoteUKeyUserService;
import com.yida.system.api.domain.SysUserUkey;

/**
 * @author yida
 * @date 2023/03/28
 */
@Component
public class SysUKeyService {
    @Autowired
    private RedisService redisService;

    private int maxRetryCount = CacheConstants.PASSWORD_MAX_RETRY_COUNT;

    private Long lockTime = CacheConstants.PASSWORD_LOCK_TIME;

    @Autowired
    private SysRecordLogService recordLogService;

    @Autowired
    private RemoteUKeyUserService remoteUKeyUserService;

    /**
     * 登录账户密码错误次数缓存键名
     * 
     * @param username 用户名
     * @return 缓存键key
     */
    private String getCacheKey(String username) {
        return CacheConstants.PWD_ERR_CNT_KEY + username;
    }

    public void validate(SysUserUkey sysUKeyUser, String password) {
        String username = sysUKeyUser.getUserName();

        Integer retryCount = redisService.getCacheObject(getCacheKey(username));

        if (retryCount == null) {
            retryCount = 0;
        }

        if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) {
            String errMsg = String.format("密码输入错误%s次，帐户锁定%s分钟", maxRetryCount, lockTime);
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, errMsg);
            throw new ServiceException(errMsg);
        }

        if (!matches(sysUKeyUser, password)) {
            retryCount = retryCount + 1;
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, String.format("密码输入错误%s次", retryCount));
            redisService.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
            throw new ServiceException("用户不存在/密码错误");
        }

        // 密码通过后校验当前Ukey是否合法
        R<?> ukeyValidateResult = remoteUKeyUserService.ukeyValidate(sysUKeyUser, SecurityConstants.INNER);
        if (R.FAIL == ukeyValidateResult.getCode()) {
            throw new ServiceException(ukeyValidateResult.getMsg());
        } else {
            clearLoginRecordCache(username);
        }
    }

    public boolean matches(SysUserUkey sysUKeyUser, String rawPassword) {
        // System.out.println("sysUKeyUser:" + sysUKeyUser.getPassword());
        // System.out.println("rawPassword:" + rawPassword);
        // System.out.println("b:" + SecurityUtils.matchesPassword(rawPassword, sysUKeyUser.getPassword()));
        return SecurityUtils.matchesPassword(rawPassword, sysUKeyUser.getPassword());
    }

    public void clearLoginRecordCache(String loginName) {
        if (redisService.hasKey(getCacheKey(loginName))) {
            redisService.deleteObject(getCacheKey(loginName));
        }
    }

    /**
     * 获取待签数据
     */
    public SysUserUkey waitSignMsg(SysUserUkey sysUKeyUser) {
        R<SysUserUkey> sysUserUkeyResult = remoteUKeyUserService.waitSignMsg(sysUKeyUser, SecurityConstants.INNER);
        if (R.isError(sysUserUkeyResult)) {
            throw new ServiceException(sysUserUkeyResult.getMsg());
        }
        return sysUserUkeyResult.getData();
    }
}
